'use strict'

//----------------Array-------------------------------------------
/**
 * 模拟Array.pop的实现
 */
Array.method('pop', function () {
    return this.splice(this.length - 1, 1)[0];
});

/**
 * 模拟Array.psuh的实现
 */
Array.method('push', function () {
    this.splice.apply(
        this,
        [this.length, 0].concat(Array.prototype.slice.apply(arguments)));

    return this.length;
});

/**
 * 模拟Array.shift实现
 */
Array.method('shift', function () {
    return this.splice(0, 1)[0];
})

var m = ['aa', 'bb', 'a', 4, 8, 15, 16, 23, 42];
m.sort(function (a, b) {
    if (a === b) {
        return 0;
    }
    if (typeof a === typeof b) {
        return a < b ? -1 : 1;
    }
    return typeof a < typeof b ? -1 : 1;
})
console.log(m);

var by = function (name) {
    return function (o, p) {
        var a, b;
        if (typeof o == 'object' && typeof p == 'object' && o && p) {
            a = o[name];
            b = p[name];
            if (a === b) {
                return 0;
            }
            if (typeof a === typeof b) {
                return a < b ? -1 : 1;
            }
            return typeof a < typeof b ? -1 : 1;
        } else {
            throw {
                name: 'Error',
                message: 'Expected an object when sorting by ' + name
            };
        }
    };
};

var by2 = function (name, minor) {
    return function (o, p) {
        var a, b;
        if (o && p && typeof o === 'object' && typeof p === 'object') {
            a = o[name];
            b = p[name];
            if (a === b) {
                return typeof minor === 'function' ? minor(o, p) : 0;
            }
            if (typeof a === typeof b) {
                return a < b ? -1 : 1;
            }
            return typeof a < typeof b ? -1 : 1;
        } else {
            throw {
                name: 'Error',
                message: 'Expected an object when sorting by ' + name
            };
        }
    }
}

Array.method('splice', function (start, deleteCount) {
    var max = Math.max,
        min = Math.min,
        delta,
        element,
        insertCount = max(arguments.length - 2, 0),
        k = 0,
        len = this.length,
        new_len,
        result = [],
        shift_count = [];

    start = start || 0;
    if (start < 0) {
        start += len;
    }
    start = max(min(start, len), 0);
    deleteCount = max(min(typeof deleteCount === 'number' ? deleteCount : len, len - start), 0);
    delta = insertCount - deleteCount;
    new_len = len+delta;
    while (k < deleteCount) {
        element = this[start + k];
        if (element !== undefined) {
            result[k] = element;
        }
        k += 1;
    }
    shift_count = len - start - deleteCount;
    if (delta < 0) {
        k = start + insertCount;
        while (shift_count) {
            this[k] = this[k - delta];
            k += 1;
            shift_count -= 1;
        }
        this.length = new_len;
    } else if (delta > 0) {
        k = 1;
        while (shift_count) {
            this[new_len - k] = this[len - k];
            k += 1;
            shift_count -= 1;
        }
    }
    for (k = 0; k < insertCount; k += 1) {
        this[start + k] = arguments[k + 2];
    }
    return result;
});

Array.method('unshift',function () {
    this.splice.apply(this,[0,0].concat(Array.prototype.slice.apply(arguments)));
    return this.length;
})


//----------------Function-------------------------------------------
Function.method('bind',function (that) {
    var method = this,
        slice = Array.prototype.slice,
        args = slice.apply(arguments,[1]);
    return function () {
        // 没看懂
        return method.apply(that,args.concat(slice.apply(arguments,[0])));
    }
})

var x = function () {
    return this.value;
}.bind({value: '666'});
alert(x());

//----------------String-------------------------------------------
String.method('charAt',function () {
    return this.slice(0,1);
})